package cn.bonoon.kernel.web.annotations;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import cn.bonoon.kernel.annotations.QueryExpression;
import cn.bonoon.kernel.filters.InitLoadFilter;
import cn.bonoon.kernel.support.entities.Persistable;

/**
 * <pre>
 * 将被定义在datagrid或treegrid界面的控制器上，使用该注解进行定义，
 * 框架会自动解释并生成相应的数据加载请求
 * 
 * 也可以定义在combobox字段的定义上；如果是定义在combob字段上
 * 并且使用的不是默认的结果对象或者是使用在combogrid上，则需要另外使用
 * 来指定界面实体存放列表的值
 * 
 * 如果是定义在combogrid，并且使用分页和查询条件，解析的时候应该自动根据
 * combogrid上的定义追加查询条件以及分页对象；动态追加查询条件的可以使用
 * XXXXXXX字段进行处理 
 * <hr/>
 * 可以使用{@link AutoDataResultClass}注解进行返回结果集的指定，该指定只针对
 * {@link cn.bonoon.kernel.web.annotations.components.AsComboGrid AsComboGrid}有效，其它情况则将自动使用对应的数据结构
 * 默认是使用x.id,x.name读值，如果需要改变属性，可以使用{@link AutoDataResultFields}进行指定
 * <hr/>
 * 如果是定义在combo上面的自动数据加载，并且该combo是允许多选的情况
 * {@link cn.bonoon.kernel.web.annotations.components.AsComboBox AsComboBox}
 * {@link cn.bonoon.kernel.web.annotations.components.AsComboGrid AsComboGrid}
 * {@link cn.bonoon.kernel.web.annotations.components.AsComboTree AsComboTree}
 * 则需要指定对选中项的选中处理，需要用到
 * {@link cn.bonoon.kernel.web.annotations.components.ComboMultipleChecker ComboMultipleChecker}
 * 
 * 如果自动加载的数据为树型结构，则可以使用{@link AjaxTreeLoader @AjaxTreeLoader}
 * 来指定是否以ajax方式加载数据
 * 
 * combo对应的数据自动加载的处理器包括：
 * {@link cn.bonoon.kernel.web.handlers.loader.ComboBoxAutoLoaderHandler ComboBoxAutoLoaderHandler}
 * {@link cn.bonoon.kernel.web.handlers.loader.ComboTreeAjaxAutoLoaderHandler ComboTreeAjaxAutoLoaderHandler}
 * {@link cn.bonoon.kernel.web.handlers.loader.ComboTreeAutoLoaderHandler ComboTreeAutoLoaderHandler}
 * {@link cn.bonoon.kernel.web.handlers.loader.ComboGridAutoLoaderHandler ComboGridAutoLoaderHandler}
 * 
 * {@link cn.bonoon.kernel.web.handlers.loader.ItemAutoLoaderHandler GridAutoLoaderHandler}
 * 
 * </pre>
 * @author jackson
 *
 */
@Target({ FIELD, TYPE })
@Retention(RUNTIME)
public @interface AutoDataLoader {
	
	/**
	 * <pre>
	 * 要从哪个数据库实体（即数据库表）进行加载数据
	 * </pre>
	 * 下一个版本中，这个字段可以不为必填。数据库对象的类型可以通过该字段所对应的数据库对象的类型来取得
	 * @return 数据库实体对象类型
	 */
	Class<? extends Persistable> value();
	
	/**
	 * <pre>
	 * 指定数据生成的处理器，可以定义加载数据之前或之后的处理事件
	 * 
	 * 默认情况下是不没有自定义的过滤器的
	 * </pre>
	 * @return 自定义处理器
	 */
	Class<? extends InitLoadFilter>[] filter() default {};
	
	/**
	 * <pre>
	 * 是否使用标准的过滤器{@link cn.bonoon.kernel.filters.StandardAutoLoadFilter StandardAutoLoadFilter}
	 * 如果是使用了表达式自己控制范围 或者使用自定义的过滤器处理了这些事情，则可以关闭默认的过滤器
	 * 
	 * 注意：默认的过滤器是可以和自定义过滤器和表达式一起使用的，都同时有效；
	 * 所以使用时请注意！！
	 * </pre>
	 * @return
	 */
	boolean useDefaultFilter() default true;
	
	/**
	 * <pre>
	 * 根据简单的规则自定义一些简单的查询条件，以满足在不使用{@link #filter()}过滤器
	 * 和{@link #queryClass()}查询对象的时候，可以通过简单的指定查询参数，直接从请
	 * 求的对象里读取值; 
	 * 规则如下：
	 * 1.直接名称，表示使用该字段，类型为字符串类型的字段来直接查询数据库
	 * </pre>
	 * @return
	 */
	QueryExpression[] queries() default {};
}
